package org.oneblog.service.tools;

import java.awt.Color;
import java.awt.Font;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import javax.imageio.ImageIO;

import org.apache.commons.io.IOUtils;

import com.alibaba.simpleimage.ImageFormat;
import com.alibaba.simpleimage.ImageWrapper;
import com.alibaba.simpleimage.SimpleImageException;
import com.alibaba.simpleimage.render.WriteParameter;
import com.alibaba.simpleimage.util.ImageReadHelper;
import com.alibaba.simpleimage.util.ImageWriteHelper;

public class GroupImageBuilder {

    private ImageWrapper baseImage;
    
    private Float radio = 1F;
    
    public GroupImageBuilder(File imageFile) throws FileNotFoundException, SimpleImageException {
        initFromFile(imageFile);
    }
    public GroupImageBuilder(URL imageUrl) throws IOException {
        initFromUrl(imageUrl);
    }
    private void initFromFile(File imageFile) throws FileNotFoundException, SimpleImageException {
        baseImage = ImageReadHelper.read(new FileInputStream(imageFile));
    }
    private void initFromUrl(URL imageUrl) throws IOException {
        BufferedImage bufferedImage = ImageIO.read(imageUrl);
        this.baseImage = new ImageWrapper(bufferedImage);
    }
    
    public GroupImageBuilder withRadio(float f) {
        this.radio = f;
        return this;
    }

    public GroupImageBuilder locateImg(File imageFile, GroupImageConf conf) throws IOException, Exception {
        long b = System.currentTimeMillis();
        this.baseImage = ImageUtilsForGroup.placeImage(this.baseImage, ImageIO.read(imageFile), 
                conf.getXWithRadio(radio), conf.getYWithRadio(radio), conf.getWidthWithRadio(radio), conf.getHeightWithRadio(radio), false, true);
        System.out.println("locateImg " + imageFile.getPath() + " " + (System.currentTimeMillis() - b));
        return this;
    }
    public GroupImageBuilder locateCircleImg(File imageFile, GroupImageConf conf) throws IOException, Exception {

        long b = System.currentTimeMillis();
        this.baseImage = ImageUtilsForGroup.placeImage(this.baseImage, ImageIO.read(imageFile), 
                conf.getXWithRadio(radio), conf.getYWithRadio(radio), conf.getWidthWithRadio(radio), conf.getHeightWithRadio(radio), true, true);
        System.out.println("locateCircleImg " + imageFile.getPath() + " " + (System.currentTimeMillis() - b));
        return this;
    }
    public GroupImageBuilder locateImg(URL imageFile, GroupImageConf conf) throws IOException, Exception {

        long b = System.currentTimeMillis();
        this.baseImage = ImageUtilsForGroup.placeImage(this.baseImage, ImageIO.read(imageFile), 
                conf.getXWithRadio(radio), conf.getYWithRadio(radio), conf.getWidthWithRadio(radio), conf.getHeightWithRadio(radio), false, true);
        System.out.println("locateImg " + imageFile.getPath() + " " + (System.currentTimeMillis() - b));
        return this;
    }
    public GroupImageBuilder locateCircleImg(URL imageFile, GroupImageConf conf) throws IOException, Exception {

        long b = System.currentTimeMillis();
        this.baseImage = ImageUtilsForGroup.placeImage(this.baseImage, ImageIO.read(imageFile), 
                conf.getXWithRadio(radio), conf.getYWithRadio(radio), conf.getWidthWithRadio(radio), conf.getHeightWithRadio(radio), true, true);
        System.out.println("locateCircleImg " + imageFile.getPath() + " " + (System.currentTimeMillis() - b));
        return this;
    }

    public GroupImageBuilder locateText(List<GroupTextConf> confs) throws IOException, Exception {

        long b = System.currentTimeMillis();
        this.baseImage = ImageUtilsForGroup.locateTxt(this.baseImage.getAsBufferedImage(), this.radio, confs);
        System.out.println("locateText " + confs + " " + (System.currentTimeMillis() - b));
        return this;
    }
    
    public void writeOut(OutputStream os) throws SimpleImageException {

        long b = System.currentTimeMillis();
        ImageWriteHelper.write(baseImage, os, ImageFormat.getImageFormat("png"), new WriteParameter());
        System.out.println("writeOut " + (System.currentTimeMillis() - b));
    }
    
    static final String folder = "/Users/wjyuian/mnt/img1/";
    
    static List<GroupTextConf> createTitles(String title) {
        List<GroupTextConf> titles = new ArrayList<>();
        int tempLen = 10, start = 0, len = title.length();
        Font font = new Font("宋体", Font.PLAIN, 25);
        int x = 80;
        int y = 615;
        while(len > tempLen + start) {
          int __delt = (start == 0 ? 1 : 0);
          String sub = title.substring(start, start + tempLen + __delt);
          
          titles.add(new GroupTextConf(sub, x, y, font, Color.WHITE, false));
          
          start += tempLen + __delt;
          y += 25;
        }
        if (start < len) {
            String sub = title.substring(start, len);

            titles.add(new GroupTextConf(sub, x, y, font, Color.WHITE, false));
        }
        
        return titles;
    }
    
    public static void main(String[] args) throws SimpleImageException, Exception {
        float radio = 120F/84;
        String bg = folder + "share_card_bg.png";
        String bg_over = folder + "share_card_over.png"; //商品图上面的遮罩
        String priceBg = folder + "price_circle.png";
        String t = folder + "gh_b5f9f166404d_258.jpg";
        
        String title = "植物主义 给孕妇的绿色安全美 基础套：橄榄油*1大米面膜*1海藻眼膜贴*1";
        String productImage = "https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1556439602825&di=38386071249cbe990c5cfdb3bb6131b0&imgtype=0&src=http%3A%2F%2Faliyunzixunbucket.oss-cn-beijing.aliyuncs.com%2Fpng%2Ff6c2b9722231ad3102c6a412a80c4423.png%3Fx-oss-process%3Dimage%2Fresize%2Cp_100%2Fauto-orient%2C1%2Fquality%2Cq_90%2Fformat%2Cjpg%2Fwatermark%2Cimage_eXVuY2VzaGk%3D%2Ct_100";
        
        String shopName = "智美优选";
        String shopLogo = "https://contenttest02.joowing.com/content_node/contents/content_agent:6b6a0c40-204f-0137-451b-0242ac1e3b59/access";
        

        List<GroupTextConf> textConfs = Arrays.asList(
                new GroupTextConf("￥199.02", 346, 486, new Font("宋体", Font.PLAIN, 30), Color.RED, false),
                new GroupTextConf("￥119", 369, 519, new Font("宋体", Font.PLAIN, 24), Color.WHITE, true),
                new GroupTextConf(shopName, 180, 777, new Font("宋体", Font.PLAIN, 25), Color.BLACK,false),
                new GroupTextConf("扫描/长按识别", 328, 720, new Font("宋体", Font.PLAIN, 25), Color.WHITE,false),
                new GroupTextConf("|", 270, 777, new Font("宋体", Font.PLAIN, 25), Color.BLACK, false));
        textConfs = new ArrayList<>(textConfs);
        textConfs.addAll(createTitles(title));
        
        long b = System.currentTimeMillis();
        
        FileOutputStream outStream = new FileOutputStream(new File(folder + "testout.png"));
        
        //生成底图
        GroupImageBuilder builder = new GroupImageBuilder(new File(bg)).withRadio(radio);
        
        //覆盖商品主图
        builder.locateImg(new URL(productImage), new GroupImageConf(73, 230, 380, 500))
        
        .locateText(Arrays.asList(new GroupTextConf(63, 730, 402, 68, Color.gray, 2)))
        .locateImg(new File(bg_over), new GroupImageConf(62, 553, 402, 513)) //遮罩
        .locateImg(new File(bg_over), new GroupImageConf(62, 578, 402, 510)) //遮罩
        
        //覆盖头像
        .locateCircleImg(new File(t), new GroupImageConf(86, 540, 50, 50))
        
        .locateCircleImg(new File(priceBg), new GroupImageConf(328, 425, 150, 150))//覆盖价格图；价格外圈图
//        .locateText(shopName, new GroupTextConf(180, 777, new Font("宋体", Font.PLAIN, 25), Color.BLACK))
        
        .locateCircleImg(new File(t), new GroupImageConf(328, 595, 111, 111)) //覆盖二维码
        
        .locateImg(new URL(shopLogo), new GroupImageConf(285, 765, 101, 35))//覆盖商户名字和logo

        //文字处理
        .locateText(textConfs);
        
        //覆盖商品标题
        
        builder.writeOut(outStream);
        
        IOUtils.closeQuietly(outStream);
        
        System.out.println(System.currentTimeMillis() - b);
    }
}
